/*
 ------------------------------------------------------------------------------
 Copyright (C) 1996-2001 Id Software, Inc.

 This file is part of the Quake source code.

 The Quake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// fileFormats.h - all file formats used in the game
//


#ifndef __FILEFORMATS_H__
#define __FILEFORMATS_H__


/*
 ==============================================================================

 TGA files are used for uncompressed images

 ==============================================================================
*/

#define TGA_IMAGE_COLORMAP				1
#define TGA_IMAGE_TRUECOLOR				2
#define TGA_IMAGE_MONOCHROME			3

struct tgaHeader_t {
	byte					bIdLength;
	byte					bColormapType;
	byte					bImageType;
	word					wColormapIndex;
	word					wColormapLength;
	byte					bColormapSize;
	word					wXOrigin;
	word					wYOrigin;
	word					wWidth;
	word					wHeight;
	byte					bPixelSize;
	byte					bAttributes;
};

/*
 ==============================================================================

 DDS files are used for compressed images

 ==============================================================================
*/

#define DDS_MAGIC						(('D' << 0) + ('D' << 8) + ('S' << 16) + (' ' << 24))

#define DDS_FOURCC_DXT1					(('D' << 0) + ('X' << 8) + ('T' << 16) + ('1' << 24))
#define DDS_FOURCC_DXT2					(('D' << 0) + ('X' << 8) + ('T' << 16) + ('2' << 24))
#define DDS_FOURCC_DXT3					(('D' << 0) + ('X' << 8) + ('T' << 16) + ('3' << 24))
#define DDS_FOURCC_DXT4					(('D' << 0) + ('X' << 8) + ('T' << 16) + ('4' << 24))
#define DDS_FOURCC_DXT5					(('D' << 0) + ('X' << 8) + ('T' << 16) + ('5' << 24))
#define DDS_FOURCC_RXGB					(('R' << 0) + ('X' << 8) + ('G' << 16) + ('B' << 24))
#define DDS_FOURCC_ATI1					(('A' << 0) + ('T' << 8) + ('I' << 16) + ('1' << 24))
#define DDS_FOURCC_ATI2					(('A' << 0) + ('T' << 8) + ('I' << 16) + ('2' << 24))

#define DDS_CAPS						0x00000001
#define DDS_HEIGHT						0x00000002
#define DDS_WIDTH						0x00000004
#define DDS_PITCH						0x00000008
#define DDS_PIXELFORMAT					0x00001000
#define DDS_MIPMAPCOUNT					0x00020000
#define DDS_LINEARSIZE					0x00080000
#define DDS_DEPTH						0x00800000

#define DDS_ALPHAPIXELS					0x00000001
#define DDS_ALPHA						0x00000002
#define DDS_FOURCC						0x00000004
#define DDS_RGB							0x00000040
#define DDS_ALPHAPREMULT				0x00008000
#define DDS_LUMINANCE					0x00020000

#define DDS_COMPLEX						0x00000008
#define DDS_TEXTURE						0x00001000
#define DDS_MIPMAP						0x00400000

#define DDS_CUBEMAP						0x00000200
#define DDS_CUBEMAP_POSITIVEX			0x00000400
#define DDS_CUBEMAP_NEGATIVEX			0x00000800
#define DDS_CUBEMAP_POSITIVEY			0x00001000
#define DDS_CUBEMAP_NEGATIVEY			0x00002000
#define DDS_CUBEMAP_POSITIVEZ			0x00004000
#define DDS_CUBEMAP_NEGATIVEZ			0x00008000
#define DDS_VOLUME						0x00200000

struct ddsPixelFormat_t {
	dword					dwSize;
	dword					dwFlags;
	dword					dwFourCC;
	dword					dwRGBBitCount;
	dword					dwRBitMask;
	dword					dwGBitMask;
	dword					dwBBitMask;
	dword					dwABitMask;
};

struct ddsHeader_t {
	dword					dwMagic;
	dword					dwSize;
	dword					dwFlags;
	dword					dwHeight;
	dword					dwWidth;
	dword					dwPitchOrLinearSize;
	dword					dwDepth;
	dword					dwMipMapCount;
	dword					dwReserved1[11];
	ddsPixelFormat_t		ddsPixelFormat;
	dword					dwCaps1;
	dword					dwCaps2;
	dword					dwReserved2[3];
};

/*
 ==============================================================================

 WAV files are used for sounds

 ==============================================================================
*/

#define WAV_FORMAT_PCM					1

struct wavFormat_t {
	word					wFormat;
	word					wChannels;
	dword					dwSamplesPerSec;
	dword					dwAvgBytesPerSec;
	word					wBlockAlign;
	word					wBitsPerSample;
};

/*
 ==============================================================================

 ROQ files are used for cinematics and in-game videos

 ==============================================================================
*/

#define ROQ_ID						0x1084

#define ROQ_CHUNK_HEADER_SIZE		8
#define ROQ_CHUNK_MAX_SIZE			65536

#define ROQ_QUAD_INFO				0x1001
#define ROQ_QUAD_CODEBOOK			0x1002
#define ROQ_QUAD_VQ					0x1011
#define ROQ_QUAD_JPEG				0x1012

#define ROQ_SOUND_MONO				0x1020
#define ROQ_SOUND_STEREO			0x1021

#define ROQ_VQ_MOT					0x0000
#define ROQ_VQ_FCC					0x4000
#define ROQ_VQ_SLD					0x8000
#define ROQ_VQ_CCC					0xC000

struct roqChunk_t {
	word					id;
	dword					size;
	word					flags;
};

struct roqQuadVector_t {
	byte					pixel[4][4];
};

struct roqQuadCell_t {
	byte					index[4];
};

/*
 ==============================================================================

 WAD2 files are used for storing general information

 ==============================================================================
*/

#define	TYP_QPIC					66

struct wadLump_t {
	int						filePos;
	int						diskSize;
	int						size;
	char					type;
	char					compression;
	char					pad1;
	char					pad2;
	char					name[16];
};

struct wadHeader_t {
	char					id[4];
	int						numLumps;
	int						infoTableOfs;
};

struct wadPic_t {
	int						width;
	int						height;
	byte					data[4];
};

/*
 ==============================================================================

 MDL files are used for animated (dynamic) render and clip models

 ==============================================================================
*/

#define MDL_ID						(('I' << 0) + ('D' << 8) + ('P' << 16) + ('O' << 24))
#define MDL_VERSION					6

#define MDL_MAX_SKINS				64
#define MDL_MAX_WIDTH				480
#define MDL_MAX_HEIGHT				480
#define MDL_MAX_VERTICES			2048
#define MDL_MAX_TRIANGLES			2048
#define MDL_MAX_FRAMES				256

#define MDL_MAX_SIZE				(1.0f/11.0f)

enum syncType_t {
	ST_TODO
};

enum mdlSkinType_t {
	MDL_SKIN_SINGLE,
	MDL_SKIN_GROUP
};

enum mdlFrameType_t {
	MDL_FRAME_SINGLE,
	MDL_FRAME_GROUP
};

struct mdlSkin_t {
	mdlSkinType_t		type;
};

struct mdlSt_t {
	int					onSeam;
	int					s;
	int					t;
};

struct mdlTriangle_t {
	int					faceFront;
	int					index[3];
};

struct mdlVertex_t {
	byte				xyz[3];
	byte				normalIndex;
};

struct mdlFrame_t {
	mdlFrameType_t		type;
};

struct mdlSingleFrame_t {
	mdlVertex_t			mins;
	mdlVertex_t			maxs;
	char				name[16];
};

struct mdlInterval_t {
	float				interval;
};

struct mdlGroupFrame_t {
	int					numFrames;
	mdlVertex_t			mins;
	mdlVertex_t			maxs;
};

struct mdlHeader_t {
	int					id;
	int					version;

	float				scale[3];
	float				translate[3];
	float				boundsRadius;
	float				eyePosition[3];

	int					numSkins;
	int					skinWidth;
	int					skinHeight;

	int					numVertices;
	int					numTriangles;
	int					numFrames;

	int					syncType;
	int					flags;
	float				size;
};

/*
 ==============================================================================

 MD3 files are used for animated (dynamic) render and clip models

 ==============================================================================
*/

#define MD3_ID						(('3' << 24) + ('P' << 16) + ('D' << 8) + 'I')
#define MD3_VERSION					15

#define MD3_MAX_TRIANGLES			8192			// Per surface
#define MD3_MAX_VERTICES			4096			// Per surface
#define MD3_MAX_MATERIALS			256				// Per surface
#define MD3_MAX_TAGS				16				// Per frame
#define MD3_MAX_FRAMES				1024			// Per model
#define MD3_MAX_SURFACES			32				// Per model

#define MD3_MAX_LODS				4

#define MD3_XYZ_SCALE				(1.0/64)		// Vertex scales

#define MD3_MAX_NAME_LENGTH			64

struct md3Frame_t {
	float				bounds[2][3];
	float				localOrigin[3];
	float				radius;
	char				name[16];
};

struct md3Tag_t {
	char				name[MD3_MAX_NAME_LENGTH];
	float				origin[3];
	float				axis[3][3];
};

struct md3Surface_t {
	int					id;

	char				name[MD3_MAX_NAME_LENGTH];
	int					flags;

	int					numFrames;				// All surfaces in a model should have the same
	int					numMaterials;			// All surfaces in a model should have the same
	int					numVertices;
	int					numTriangles;

	int					ofsTriangles;
	int					ofsMaterials;			// Offset from start of md3Surface_t
	int					ofsSt;					// Texture coords are common for all frames
	int					ofsVertices;			// numVerts * numFrames
	int					ofsEnd;					// Next surface follows
};

struct md3Material_t {
	char				name[MD3_MAX_NAME_LENGTH];
	int					materialIndex;			// For in-game use
};

struct md3Triangle_t {
	int					index[3];
};

struct md3St_t {
	float				st[2];
};

struct md3Vertex_t {
	short				xyz[3];
	short				normal;
};

struct md3Header_t {
	int					id;
	int					version;

	char				name[MD3_MAX_NAME_LENGTH];		// Model name
	int					flags;

	int					numFrames;
	int					numTags;			
	int					numSurfaces;
	int					numSkins;

	int					ofsFrames;				// Offset for first frame
	int					ofsTags;				// numTags * numFrames
	int					ofsSurfaces;			// First surface, others follow
	int					ofsEnd;					// End of file
};

/*
 ==============================================================================

 SPR files are used for objects that can not be rendered properly using polygons

 ==============================================================================
*/

#define SPR_ID						(('P' << 24) + ('S' << 16) + ('D' << 8) + ('I'))
#define SPR_VERSION					1

#define SPR_MAX_FRAMES				14

enum sprFrameType_t {
	SPR_SINGLE,
	SPR_GROUP
};

struct sprHeader_t {
	int						id;
	int						version;

	int						type;

	float					radius;

	int						width;
	int						height;

	int						numFrames;

	float					beamLength;

	syncType_t				syncType;
};

/*
 ==============================================================================

 BSP files are used for maps

 ==============================================================================
*/

#define BSP_VERSION					29

#define BSP_MAX_ENTITIES			65536
#define BSP_MAX_PLANES				32767
#define BSP_MAX_TEXTURES			512
#define BSP_MAX_VERTICES			65535
#define BSP_MAX_PVS					0x100000
#define BSP_MAX_NODES				32767
#define BSP_MAX_TEXINFO				4096
#define BSP_MAX_FACES				65535
#define BSP_MAX_LIGHTING			0x100000
#define BSP_MAX_CLIP_NODES			32767
#define BSP_MAX_LEAFS				8192
#define BSP_MAX_MARKSURFACES		65535
#define BSP_MAX_EDGES				256000
#define BSP_MAX_SURFEDGES			512000
#define BSP_MAX_INLINEMODELS		256
#define BSP_MAX_HULLS				4

#define MIN_WORLD_COORD				-131072.0f
#define MAX_WORLD_COORD				131072.0f

#define MAX_WORLD_SIZE				(MAX_WORLD_COORD - MIN_WORLD_COORD)

enum headerLump_t {
	LUMP_ENTITIES,
	LUMP_PLANES,
	LUMP_TEXTURES,
	LUMP_VERTICES,
	LUMP_PVS,
	LUMP_NODES,
	LUMP_TEXINFO,
	LUMP_FACES,
	LUMP_LIGHTING,
	LUMP_CLIPNODES,
	LUMP_LEAFS,
	LUMP_MARKSURFACES,
	LUMP_EDGES,
	LUMP_SURFEDGES,
	LUMP_INLINEMODELS,
	NUM_HEADER_LUMPS
};

struct bspLump_t {
	int						offset;
	int						length;
};

struct bspHeader_t {
	int						version;

	bspLump_t				lumps[NUM_HEADER_LUMPS];
};

struct bspPlane_t {
	float					normal[3];
	float					dist;
	int						type;
};

struct bspMipTexture_t {
	int						numMipTextures;
	int						dataOfs[4];
};

struct bspVertex_t {
	float					point[3];
};

struct bspNode_t {
	int						planeNum;

	short					children[2];

	short					mins[3];
	short					maxs[3];

	ushort					firstFace;
	ushort					numFaces;
};

struct bspTexInfo_t {
	float					vecs[2][4];
	int						miptex;
	int						flags;
};

struct bspFace_t {
	short					planeNum;
	short					side;

	int						firstEdge;
	short					numEdges;
	short					texInfo;

	byte					styles[4];
	int						lightOfs;
};

struct bspClipNode_t {
	int						planeNum;
	short					children[2];
};

struct bspLeaf_t {
	int						contents;
	int						visOfs;

	short					mins[3];
	short					maxs[3];

	ushort					firstMarkSurface;
	ushort					numMarkSurfaces;

	byte					ambientLevel[4];
};

struct bspEdge_t {
	ushort					v[2];
};

struct bspInlineModel_t {
	float					mins[3];
	float					maxs[3];
	float					origin[3];

	int						headNode[4];

	int						visLeafs;

	int						firstFace;
	int						numFaces;
};


#endif	// __FILEFORMATS_H__